package com.dingdang.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingdang.data.Result;
import com.dingdang.em.ResultEnum;
import com.dingdang.entity.CarLabel;
import com.dingdang.entity.TbCarGoods;
import com.dingdang.entity.TbUser;
import com.dingdang.service.QrqmService;
import com.dingdang.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
@RequestMapping("guessLike")
@Api("千人千面(猜你喜欢)")
public class QrqmController {


    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private QrqmService qrqmService;

    @Resource
    private RedisTemplate redisTemplate;

    @PostMapping("/goToLike")
    public Result guessLike(HttpServletRequest request, @RequestParam(defaultValue = "1")Integer pageNum,
                            @RequestParam(defaultValue = "10")Integer pageSize){

        //1.首先获取登录态(登录态因为使用的是单点登录所以需要令牌才能获取登录态)
        String header = request.getHeader("authToken");//TODO:这里是没有登录时走的逻辑

        if (StringUtils.isEmpty(header)){

            //2.如果用户没有登录随机查询出几条数据返回,这里调用接口查询es中的数据
            List<TbCarGoods> tbCarGoods = qrqmService.selectRandom(pageNum, pageSize);

            return Result.response(ResultEnum.SUCCESS).setData(tbCarGoods);

        }
        //TODO:这里是登录成功后走的业务逻辑
        Claims claims = jwtUtil.parseJwt(header);

        String id = claims.getId();
        //这个是获取用户的信息subject字符串格式
        String subject = claims.getSubject();

        TbUser tbUser = JSONObject.parseObject(subject, TbUser.class);
        //去redis中查询是否有数据
        Boolean persist = redisTemplate.hasKey("userTime"+tbUser.getUid());
        Boolean persist1 = redisTemplate.hasKey("user"+tbUser.getUid());

        if (persist || persist1){//为true是存在
            //3.如果用户登录并且redis中存在key,则拿着用户的ID去查询redis中的车辆标签(每个用户的标签都会定期删除)
            ZSetOperations zSet = redisTemplate.opsForZSet();
            Set<String> set = zSet.reverseRangeByScore("user" + tbUser.getUid(), 0, 3);
            Set<String> carLabels = zSet.reverseRangeByScore("user" + tbUser.getUid(), 0, 3);
            Iterator<String> iterator1 = carLabels.iterator();
            Iterator<String> iterator = set.iterator();
            //取出以后将时间的zset循环前三个,去判断在分数中的zset是否存在,以及分数是否大于等于3
            List<String> list = new ArrayList<>();
            while (iterator1.hasNext()){
                Double score = zSet.score("user" + tbUser.getUid(), iterator1.next());
                if (score >= 3){
                    list.add(iterator1.next());
                    zSet.incrementScore("userLike"+tbUser.getUid(),iterator1.next(),3);
                }else {
                    if (iterator1.hasNext()){
                        //删除小于3的
                        zSet.remove("user" + tbUser.getUid(), iterator1.next());
                    }
                }
            }
            //如果数组是空的就直接存放,大key为"user" + tbUser.getUid()的前三名
            while (iterator.hasNext()){
                zSet.incrementScore("userLike"+tbUser.getUid(),iterator.next(),3);
            }
            List<TbCarGoods> tbCarGoodsList = new ArrayList<>();
            //根据这些标签去ES索引库中查询数据,并返回给前台
            Set<ZSetOperations.TypedTuple> userLike = zSet.rangeWithScores("userLike" + tbUser.getUid(), 0, -1);
            List<TbCarGoods> list1 = qrqmService.selectByLabels();
            /*for (TbCarGoods tbCarGoods : list1) {
                String labelId = tbCarGoods.getLabelId();
                List<String> labelIdList = JSONObject.parseObject(labelId, List.class);
                while (iterator2.hasNext()){
                    if (labelIdList.contains(iterator2.next())){
                        //如果包含于就放入一个list中
                        tbCarGoodsList.add(tbCarGoods);
                    }
                }
            }*/
            for (TbCarGoods tbCarGoods : list1) {
                String labelId = tbCarGoods.getLabelId();
                List<String> labelIdList = JSONObject.parseObject(labelId, List.class);
                for (ZSetOperations.TypedTuple typedTuple : userLike) {
                    if (labelIdList.contains(Integer.valueOf((String) typedTuple.getValue()))){
                        //如果包含于就放入一个list中

                        tbCarGoodsList.add(tbCarGoods);
                    }
                }
            }
            ArrayList<TbCarGoods> tbCarGoodsArrayList = new ArrayList<>(new HashSet<TbCarGoods>(tbCarGoodsList));
            return Result.response(ResultEnum.SUCCESS).setData(tbCarGoodsArrayList);
            //qrqmService.selectByLabels(carLabels);
        }else {//不存在
            //判断是否有这个key存在随,如果没有就说明用户第一次登录(机推几个车辆)
            List<TbCarGoods> list = qrqmService.selectRandom(pageNum, pageSize);
            return Result.response(ResultEnum.SUCCESS).setData(list);
        }
    }




}
